<template>
  <div ref="listSearchTable" class="list-search-table">
    <div ref="listSearchTableFilter" class="list-search-table-filter">
      <a-form :model="tableFilter.form">
        <a-row :gutter="24">
          <a-col :span="12">
            <a-form-item label="所属应用/客户端" v-bind="tableFilterValidateInfos.clientKey">
              <a-cascader
                v-model:value="tableFilter.form.clientKey"
                :options="tableFilter.form.domainAndClientOptions"
                :show-search="{
                  filter: (inputValue, path) =>
                    path.some((option) => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1),
                }"
                placeholder="请选择所属应用/客户端"
              />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="库名" v-bind="tableFilterValidateInfos.dbName">
              <a-input v-model:value="tableFilter.form.dbName" placeholder="请输入库名" />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="表名" v-bind="tableFilterValidateInfos.tableName">
              <a-input v-model:value="tableFilter.form.tableName" placeholder="请输入表名" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-row v-show="showAdvanceFilter" :gutter="24">
          <a-col :span="6">
            <a-form-item label="主键值" v-bind="tableFilterValidateInfos.primaryKey">
              <a-input v-model:value="tableFilter.form.primaryKey" placeholder="请输入主键值" />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="字段名" v-bind="tableFilterValidateInfos.fieldName">
              <a-input v-model:value="tableFilter.form.fieldName" placeholder="请输入字段名" />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="类型">
              <a-select
                ref="select"
                v-model:value="tableFilter.form.type"
                placeholder="请选择类型"
                v-bind="tableFilterValidateInfos.type"
              >
                <a-select-option value="INSERT">INSERT</a-select-option>
                <a-select-option value="UPDATE">UPDATE</a-select-option>
                <a-select-option value="DELETE">DELETE</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="调用类" v-bind="tableFilterValidateInfos.typeName">
              <a-input v-model:value="tableFilter.form.typeName" placeholder="请输入调用类" />
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item label="调用方法" v-bind="tableFilterValidateInfos.methodName">
              <a-input v-model:value="tableFilter.form.methodName" placeholder="请输入调用方法" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="变更时间" v-bind="tableFilterValidateInfos.changeTime">
              <a-range-picker v-model:value="tableFilter.form.changeTime" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
      <div style="height: 32px">
        <a-space style="float: right">
          <a-button type="primary" @click.prevent="onTableFilterSubmit">查询</a-button>
          <a-button @click="onTableFilterReset">重置</a-button>
          <a-button type="link" @click="onTableShowAdvanceFilter">
            <span>高级筛选</span>
            <down-outlined v-if="!showAdvanceFilter" />
            <up-outlined v-else />
          </a-button>
        </a-space>
      </div>
    </div>
    <a-table
      :columns="table.columns"
      :data-source="table.data"
      bordered
      :pagination="false"
      :loading="loading"
      :scroll="tableScroll"
      @resize-column="(w, col) => (col.width = w)"
    ></a-table>
    <div ref="listSearchTablePagination" class="list-search-table-pagination">
      <a-pagination
        v-model:current="tablePagination.current"
        :total="tablePagination.total"
        @change="onTablePaginationChange"
      />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, Ref, nextTick, reactive, onMounted, toRaw } from 'vue'
import { Form } from 'ant-design-vue'
import type { ShowSearchType } from 'ant-design-vue/es/cascader'
import { DownOutlined, UpOutlined } from '@ant-design/icons-vue'
import dayjs from 'dayjs'
import useLoading from '@/hooks/loading'
import { getLogList, getDomainAndClientList } from './factory'

const { loading, loadingText, setLoading } = useLoading(true)
/****************************************
 *               表格样式                *
 ****************************************/

const listSearchTable: Ref = ref(null)
const listSearchTableFilter: Ref = ref(null)

const tableScroll = reactive<{ x?: number; y?: number }>({})
const onTableShowAdvanceFilter = () => {
  showAdvanceFilter.value = !showAdvanceFilter.value
  nextTick(() => {
    tableScroll.y = listSearchTable.value.clientHeight - listSearchTableFilter.value.clientHeight - 64 - 72
    console.log(tableScroll.y)
  })
}
nextTick(() => {
  tableScroll.y = listSearchTable.value.clientHeight - listSearchTableFilter.value.clientHeight - 64 - 72
  console.log(tableScroll.y)
})

const showAdvanceFilter = ref(false)
/****************************************
 *              表格筛选器                *
 ****************************************/

const tableFilter = reactive({
  form: {
    clientKey: '',
    domainAndClientOptions: [],

    dbName: '',
    tableName: '',
    primaryKey: '',
    fieldName: '',
    type: '',
    typeName: '',
    methodName: '',
    changeTime: [],
    changeTimeStart: '',
    changeTimeEnd: '',
  },
  rules: {},
})

const {
  resetFields: onTableFilterReset,
  validate: onTableFilterValidate,
  validateInfos: tableFilterValidateInfos,
} = Form.useForm(tableFilter.form, tableFilter.rules, {
  onValidate: (...args) => console.log(...args),
})

const generateQuery = () => {
  let _queryForm = JSON.parse(JSON.stringify(toRaw(tableFilter.form)))

  console.log(_queryForm)

  // clientKey处理 级联选择器结果是数组要转string
  if (Array.isArray(_queryForm.clientKey) && _queryForm.clientKey.length === 3) {
    _queryForm.clientKey = _queryForm.clientKey.pop()
  }

  // 日期处理
  if (_queryForm.changeTime.length > 1) {
    _queryForm.changeTimeStart = dayjs(_queryForm.changeTime[0]).format('YYYY-MM-DD 00:00:00')
    _queryForm.changeTimeEnd = dayjs(_queryForm.changeTime[1]).format('YYYY-MM-DD 23:59:59')
  }

  // 去掉不要的字段
  delete _queryForm['domainAndClientOptions']
  delete _queryForm['changeTime']

  return {
    ..._queryForm,
    pageNo: tablePagination.current,
    pageSize: tablePagination.pageSize,
  }
}

const onTableFilterSubmit = () => {
  onTableFilterValidate()
    .then(() => {
      tablePagination.current = 1
    })
    .then(() => fetchTableData())
    .catch((err) => {
      console.log('error', err)
    })
}
/****************************************
 *               表格主体                 *
 ****************************************/
const table = reactive({
  // 表格列
  columns: [
    {
      title: '应用',
      dataIndex: 'appName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
      fixed: 'left',
    },
    {
      title: '客户端',
      dataIndex: 'clientName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '链路ID',
      dataIndex: 'traceId',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '调用类',
      dataIndex: 'typeName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,

      maxWidth: 200,
    },
    {
      title: '调用方法',
      dataIndex: 'methodName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '库名',
      dataIndex: 'dbName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '表名',
      dataIndex: 'tableName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '主键值',
      dataIndex: 'primaryKey',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '类型',
      dataIndex: 'type',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '字段名',
      dataIndex: 'fieldName',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '变更前',
      dataIndex: 'beforeValue',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '变更后',
      dataIndex: 'afterValue',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '变更人',
      dataIndex: 'changedBy',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
    {
      title: '变更时间',
      dataIndex: 'changeTime',
      resizable: true,
      width: 100,
      minWidth: 100,
      ellipsis: true,
    },
  ],
  // 表格数据
  data: [],
})
/****************************************
 *              表格分页器                *
 ****************************************/
const tablePagination = reactive({
  pageCount: 0,
  current: 1,
  pageSize: 10,
  total: 0,
})
const onTablePaginationChange = (current) => {
  // console.log(pagination)

  // const { current } = pagination
  tablePagination.current = current
  fetchTableData()
}

/****************************************
 *             表格请求数据               *
 ****************************************/
const fetchTableData = async () => {
  try {
    setLoading(true)
    const query = generateQuery()
    const res = await getLogList(query)
    const { dataList, pageCount, pageNo, pageSize, totalCount } = res.data

    table.data = dataList

    tablePagination.pageCount = pageCount
    tablePagination.total = Number(totalCount)
  } catch (error) {
    console.error(error)
  } finally {
    setLoading(false)
  }
}

const fetchCascaderOptions = async () => {
  const res = await getDomainAndClientList()

  const domainList = res.data

  domainList.forEach((domain) => {
    domain.list.forEach((app) => {
      app.clientList.forEach((client) => {
        client['value'] = client.clientKey
        client['label'] = client.name
      })

      app['value'] = app.appKey
      app['label'] = app.name
      app['children'] = app.clientList
    })

    domain['value'] = domain.domain
    domain['label'] = domain.domain
    domain['children'] = domain.list
    delete domain['domain']
    delete domain['list']
  })

  tableFilter.form.domainAndClientOptions = domainList
}

/**
 * 生命周期 onMounted
 */
onMounted(async () => {
  // 获取级联选择器选项
  await fetchCascaderOptions()
  // 初始化请求数据
  await fetchTableData()
})
</script>

<style lang="less" scoped></style>
